package controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import model.Computation;
import view.InputPanel;
import view.MainFrame;
import view.MainPanel;
import view.PopulationGraph;
import view.OutputTable;
import view.SampleGraph;

public class Main {
    private MainPanel mainPanel;
    private InputPanel inputPanel;
    private OutputTable outputTable;
    private PopulationGraph populationGraph;
    private SampleGraph sampleGraph;
    
    public static void main(String[] args) {
        new Main();
    }
    
    public Main() {
        MainFrame frame = new MainFrame();
        mainPanel = new MainPanel();
        frame.setPanel(mainPanel);
        inputPanel = mainPanel.getInputPanel();
        initInputs();
        outputTable = mainPanel.getOutputTable();
        populationGraph = mainPanel.getPopulationGraph();
        sampleGraph = mainPanel.getSampleGraph();
        
        inputPanel.addUpdateListener(update());
        inputPanel.addLowerSpinnerListener(lowerSpinner());
        inputPanel.addUpperSpinnerListener(upperSpinner());
        inputPanel.addNSpinnerListener(populationSpinner());
        inputPanel.addnSpinnerListener(sampleSpinner());
        inputPanel.addPopSizeSliderListener(popSizeSlider());
        inputPanel.addSampleSizeSliderListener(sampleSizeSlider());
    }
    
    private void initInputs() {
        inputPanel.setXLower(inputPanel.getXLower());
        inputPanel.setXUpper(inputPanel.getXUpper());
        inputPanel.setPopulationSize(inputPanel.getPopulationSize());
        inputPanel.setSampleSize(inputPanel.getSampleSize());
        
     }
    
    private ActionListener update() {
        return new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ev) {

            System.out.println("-------Update----->");
            updateOutputs(inputPanel.getXLower(),
                         inputPanel.getXUpper(),
                         inputPanel.getPopulationSize(),
                         inputPanel.getSampleSize(),
                         inputPanel.getGraphType());     
        }
        };
    }
    
    private ChangeListener lowerSpinner() {
        return new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent arg0) {
      	
            int xLower = inputPanel.getXLower();
            int xUpper = inputPanel.getXUpper();
            int populationSize = inputPanel.getPopulationSize();
            int sampleSize = inputPanel.getSampleSize();
            String graph = inputPanel.getGraphType();
            
            //updateOutputs(xLower, xUpper, populationSize,sampleSize, graph);
            /*
            if (xLower < 0) {
                xLower = 0;
            }
            
            if (xLower > xUpper) {
                xUpper = xLower;
                inputPanel.setXUpper(xUpper);
                inputPanel.setXLower(xLower);   
            }
            */
            
           // updateOutputs(xLower, xUpper, n, p);
        }
        };
    }
    

    
    private ChangeListener upperSpinner() {
        return new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent arg0) {
        
            int xLower = inputPanel.getXLower();
            int xUpper = inputPanel.getXUpper();
            int populationSize = inputPanel.getPopulationSize();
            int sampleSize = inputPanel.getSampleSize();
            String graph = inputPanel.getGraphType();
            
            //updateOutputs(xLower, xUpper, populationSize,sampleSize, graph);
            /*
            if (xUpper > Computation.MAX_X) {
                xUpper = Computation.MAX_X;
            }
            
            if (xUpper < xLower) {
                xLower = xUpper;
                inputPanel.setXUpper(xUpper);
                inputPanel.setXLower(xLower);   
            }
            
            if (xUpper < populationSize) {
                populationSize = xUpper;
                inputPanel.setPopulationSize(populationSize);
            }
            */
        }
        };
    }
    
    private ChangeListener populationSpinner() {
        return new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent arg0) {
        	
            int xUpper = inputPanel.getXUpper();
            int xLower = inputPanel.getXLower();
            int populationSize = inputPanel.getPopulationSize();
            int sampleSize = inputPanel.getSampleSize();
            String graph = inputPanel.getGraphType();
            
            //updateOutputs(xLower, xUpper, populationSize,sampleSize, graph);
            /*
            if (populationSize > xUpper) {
                populationSize = xUpper;
                inputPanel.setXUpper(populationSize);
            }
            */
            //updateOutputs(xLower, xUpper, n, p);
        }
        };
    }
    
    private ChangeListener sampleSpinner() {
        return new ChangeListener() {

        @Override
        public void stateChanged(ChangeEvent arg0) {
        	int xLower = inputPanel.getXLower();
            int xUpper = inputPanel.getXUpper();
            int populationSize = inputPanel.getPopulationSize();
            int sampleSize = inputPanel.getSampleSize();
            String graph = inputPanel.getGraphType();
            /*
            //updateOutputs(xLower, xUpper, populationSize,sampleSize, graph);
            /*
            if (populationSize < sampleSize) {
                sampleSize = populationSize;
                inputPanel.setSampleSize(sampleSize);
            }
            */
            //updateOutputs(xLower, xUpper, n, p);
        }
        };
    }
    
    private ChangeListener sampleSizeSlider()
    {	
		return new ChangeListener(){
			@Override
			 public void stateChanged(ChangeEvent e) {
				 JSlider s_slider = (JSlider)e.getSource();
					
					int xLower = inputPanel.getXLower();
		            int xUpper = inputPanel.getXUpper();
		            int populationSize = inputPanel.getPopulationSize();
		            int sampleSize = s_slider.getValue();
		            String graph = inputPanel.getGraphType();
		            
		            inputPanel.setSampleSize(s_slider.getValue());
		            System.out.println("Lower " + xLower + "Upper " + xUpper + "populationSize" + populationSize + "sampleSize" + sampleSize);
		
				 //inputPanel.setSampleSize(s_slider.getValue());
		         System.out.println("Sample size"+s_slider.getValue());
				
		         
		         /*
		         updateOutputs(inputPanel.getXLower(),
                         inputPanel.getXUpper(),
                         inputPanel.getPopulationSize(),
                         inputPanel.getSampleSize(),
                         inputPanel.getGraphType());     
		          */  
		         updateOutputs(xLower,xUpper,populationSize,sampleSize,graph);
				 //updateOutputs(int xLower, int xUpper, int populationSize, int sampleSize, String graphType)
			 }
		};
    }
    
    private ChangeListener popSizeSlider()
    {	
		return new ChangeListener(){
			@Override
			 public void stateChanged(ChangeEvent e) {
		/*
					int xLower = inputPanel.getXLower();
		            int xUpper = inputPanel.getXUpper();
		            int populationSize = inputPanel.getPopulationSize();
		            int sampleSize = inputPanel.getSampleSize();
		            String graph = inputPanel.getGraphType();
		            */
				 JSlider slider = (JSlider)e.getSource();
				 
				 inputPanel.setPopulationSize(slider.getValue());
				 //inputPanel.setSampleSize();

		         System.out.println("Pop size"+slider.getValue());
					updateOutputs(inputPanel.getXLower(),
	                         inputPanel.getXUpper(),
	                         inputPanel.getPopulationSize(),
	                         inputPanel.getSampleSize(),
	                         inputPanel.getGraphType());     
				
		            
				 //updateOutputs(xLower,xUpper,populationSize,sampleSize,graph);
				 //updateOutputs(int xLower, int xUpper, int populationSize, int sampleSize, String graphType)
			 }
		};
    }
    
    
    
    private boolean verifyValues(int xLower, int xUpper, int populationSize, int sampleSize) {
        boolean verified = true;
        
        if (xLower > xUpper || 
                xLower > populationSize ||
                xUpper < populationSize ||
                xLower < 0 ||
                populationSize < sampleSize)
            
            verified = true;
      
        return verified;
    }
    
    private boolean possible(int xLower, int xUpper, int populationSize){
    	boolean divisible = false;
    	
    	if(populationSize % ((xUpper+1)-xLower) == 0)
    		divisible = true;
    	
    	return divisible;
    }
    
 
    
    private void updateOutputs(int xLower, int xUpper, int populationSize, int sampleSize, String graphType) {
            if(graphType.equals("uniform")){
            	if(possible(xLower, xUpper, populationSize)){
            		  Computation computation = new Computation(xLower, xUpper, populationSize, sampleSize, graphType);
                      
                      inputPanel.updateData(computation);
                      outputTable.updateData(computation);
                      populationGraph.updateData(computation);
                      sampleGraph.updateData(computation);
            	}
            }
            else{
            	Computation computation = new Computation(xLower, xUpper, populationSize, sampleSize, graphType);
                
                inputPanel.updateData(computation);
                outputTable.updateData(computation);
                populationGraph.updateData(computation);
                sampleGraph.updateData(computation);
            }
            	
    }
    
    
}
